home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / games / ted5.zip / IGRABSRC.ZIP / GRABEGA.BAK < prev    next >
Text File  |  1993-02-04  |  12KB  |  568 lines

  1. ////////////////////////////////////////////////////////////
  2. //
  3. // EGA Grabbing
  4. //
  5. ////////////////////////////////////////////////////////////
  6. #include "igrab.h"
  7. #pragma hdrstop
  8.  
  9. OptStruct Optimum;
  10.  
  11. ////////////////////////////////////////////////////////////
  12. //
  13. // EGAblit : blits an EGA shape from memory to the EGA screen
  14. //
  15. ////////////////////////////////////////////////////////////
  16. void EGAblit(int x,int y,int width,int height,char huge *buffer)
  17. {
  18.  unsigned ESreg,DIreg,SIreg,DSreg,where,oheight,owidth,addx,addy;
  19.  
  20.  if (noshow || SkipToStart)
  21.    return;
  22.  // Preclipping
  23.  if (x<0 || y<0)
  24.    return;
  25.  
  26.  if (x>39 || y>199)
  27.    globalx=globaly=globalmaxh=x=y=0;
  28.  
  29.  addx=addy=0;
  30.  if (x+width>39)
  31.    {
  32.     owidth=width;
  33.     width=40-x;
  34.     addx=owidth-width;
  35.    }
  36.  if (y+height>199)
  37.    {
  38.     oheight=height;
  39.     height=200-y;
  40.     addy=(oheight-height)*owidth;
  41.    }
  42.  
  43.  outport(GCindex,GCmode);
  44.  DSreg=FP_SEG(buffer);
  45.  SIreg=FP_OFF(buffer);
  46.  where=y*40+x;
  47.  
  48.  asm    push    ds
  49.  
  50.  asm    cld
  51.  asm    mov    si,SIreg
  52.  asm    mov    ax,DSreg
  53.  asm    mov    ds,ax
  54.  asm    mov    bx,1
  55.  LOOP0:
  56.  asm    mov    dx,SCindex
  57.  asm    mov    ax,SCmapmask
  58.  asm    mov    ah,bl
  59.  asm    out    dx,ax        // set plane to write to
  60.  
  61.  asm    mov    di,where
  62.  asm    mov    ax,0xa000
  63.  asm    mov    es,ax
  64.  
  65.  asm    mov    dx,height
  66.  LOOP1:
  67.  asm    mov    cx,width
  68.  asm    rep movsb
  69.  asm    mov    cx,addx        // any to finish up horizontally?
  70.  asm    jcxz    LOOP1a
  71.  asm    rep lodsb
  72.  
  73.  LOOP1a:
  74.  asm    sub    di,width
  75.  asm    add    di,40
  76.  asm    dec    dx
  77.  asm    jnz    LOOP1
  78.  asm    mov    cx,addy        // any to finish up vertically?
  79.  asm    jcxz    LOOP1b
  80.  asm    rep lodsb
  81.  
  82.  LOOP1b:
  83.  asm    mov    ax,si
  84.  asm    shr    ax,1
  85.  asm    shr    ax,1
  86.  asm    shr    ax,1
  87.  asm    shr    ax,1
  88.  asm    mov    bx,ds
  89.  asm    add    bx,ax
  90.  asm    mov    ds,bx
  91.  asm    and    si,0x0f
  92.  
  93.  asm    shl    bx,1        // make sure we write to all planes!
  94.  asm    cmp    bx,16
  95.  asm    jb    LOOP0
  96.  
  97.  asm    pop    ds
  98. }
  99.  
  100.  
  101. ////////////////////////////////////////////////////////////
  102. //
  103. // DoEGAblit : handles output of EGA grabs to the screen
  104. //
  105. ////////////////////////////////////////////////////////////
  106. void DoEGAblit(int x,int y,int width,int height)
  107. {
  108.  if (noshow || SkipToStart)
  109.    return;
  110.  
  111.  if (nostacking)
  112.    {
  113.     globalx=x;
  114.     globaly=y;
  115.    }
  116.  
  117.  EGAblit(globalx,globaly,width,height,databuffer+offset);
  118.  if (!nostacking)
  119.    {
  120.     globalx+=width;
  121.     if (globalmaxh<height)
  122.       globalmaxh=height;
  123.     if (globalx>40-width)
  124.       {
  125.        globaly+=globalmaxh;
  126.        globalx=globalmaxh=0;
  127.       }
  128.    }
  129. }
  130.  
  131.  
  132. ////////////////////////////////////////////////////////////
  133. //
  134. // EGAgrab : grabs any EGA shape from the screen buffer in main memory
  135. //           with INLINE asm for *FAST* grab!
  136. //         Of course, by John Romero!
  137. //
  138. // NOTE: I expect X & WIDTH to be in BYTE values, not pixels!
  139. //
  140. ////////////////////////////////////////////////////////////
  141. void EGAgrab(int x,int y,int width,int height,long offset)
  142. {
  143.  unsigned ESreg,DIreg,SIreg,DSreg,scrnwid;
  144.  long off,size;
  145.  
  146.  
  147.  scrnwid=CurrentLBM.width/8;
  148.  size=scrnwid*CurrentLBM.height;    // EGA plane calculation
  149.  
  150.  for (i=0;i<4;i++)
  151.    {
  152.     // FROM
  153.     off=size*i+((CurrentLBM.width/8)*y+x);
  154.     SIreg=FP_OFF(lbmscreen)+(off&15);
  155.     DSreg=FP_SEG(lbmscreen)+off/16;
  156.  
  157.     // TO
  158.     ESreg=FP_SEG(databuffer)+offset/16;
  159.     DIreg=FP_OFF(databuffer)+(offset&15);
  160.  
  161.     asm        push    si
  162.     asm        push    di
  163.     asm        push    ds
  164.  
  165.     asm        mov    bx,height
  166.     asm        mov    dx,width
  167.  
  168.     asm        mov    es,ESreg
  169.     asm        mov    di,DIreg
  170.     asm        mov    si,SIreg
  171.     asm        mov    ax,DSreg
  172.     asm        mov    ds,ax
  173.     asm        cld
  174.  
  175.     LOOP1:
  176.  
  177.     asm        mov    cx,dx
  178.     asm        rep movsb
  179.  
  180.     asm        sub    si,dx
  181.     asm        add    si,scrnwid
  182.     asm        dec    bx
  183.     asm        jnz    LOOP1
  184.  
  185.     asm        pop    ds
  186.     asm        pop    di
  187.     asm        pop    si
  188.  
  189.     offset+=width*height;
  190.    }
  191. }
  192.  
  193. ////////////////////////////////////////////////////////////
  194. ////////////////////////////////////////////////////////////
  195. //
  196. // MASKED STUFF
  197. //
  198. ////////////////////////////////////////////////////////////
  199. ////////////////////////////////////////////////////////////
  200.  
  201.  
  202. ////////////////////////////////////////////////////////////
  203. //
  204. // EGAMblit : blits an EGA masked shape from memory to the EGA screen
  205. //
  206. ////////////////////////////////////////////////////////////
  207. void EGAMblit(int x,int y,int width,int height,char huge *buffer)
  208. {
  209.  unsigned MASKoff,DATAoff,ESreg,DIreg,SIreg,DSreg,where,oheight,owidth,addx,addy;
  210.  
  211.  if (noshow || SkipToStart)
  212.    return;
  213.  // Preclipping
  214.  if (x<0 || y<0)
  215.    return;
  216.  
  217.  addx=addy=0;
  218.  owidth=width;
  219.  oheight=height;
  220.  
  221.  if (x+width>39)
  222.    {
  223.     width=40-x;
  224.     addx=owidth-width;
  225.    }
  226.  if (y+height>199)
  227.    {
  228.     height=200-y;
  229.     addy=(oheight-height)*owidth;
  230.    }
  231.  
  232.  outport(GCindex,GCmode);
  233.  DSreg=FP_SEG(buffer);
  234.  MASKoff=FP_OFF(buffer);
  235.  DATAoff=FP_OFF((char far *)buffer+owidth*oheight);
  236.  where=y*40+x;
  237.  
  238.  asm    push    si
  239.  asm    push    di
  240.  asm    push    ds
  241.  asm    pushf
  242.  
  243.  asm    mov    dx,DATAoff
  244.  asm    mov    ds,DSreg
  245.  asm    mov    bx,1
  246.  asm    mov    ah,0
  247.  LOOP0:
  248.  asm    push    dx
  249.  asm    push    ax
  250.  
  251.  asm    mov    dx,GCindex
  252.  asm    mov    al,GCreadmap
  253.  asm    out    dx,ax        // set plane to read from!
  254.  asm    mov    dx,SCindex
  255.  asm    mov    ax,SCmapmask
  256.  asm    mov    ah,bl
  257.  asm    out    dx,ax        // set plane to write to!
  258.  
  259.  asm    mov    si,MASKoff
  260.  asm    mov    di,where
  261.  asm    mov    ax,0xa000
  262.  asm    mov    es,ax
  263.  
  264.  asm    pop    ax
  265.  asm    pop    dx
  266.  
  267.  asm    mov    bh,BYTE PTR height
  268.  LOOP1:
  269.  asm    mov    cx,width
  270.  LOOP1c:
  271.  asm    mov    al,[es:di]
  272.  asm    and    al,[si]        // get mask byte (SI=mask data)
  273.  asm    inc    si
  274.  asm    xchg    si,dx        // SI now = EGA data
  275.  asm    or    al,[si]
  276.  asm    inc    si
  277.  asm    xchg    si,dx        // SI now = MASK data
  278.  asm    stosb
  279.  asm    loop LOOP1c
  280.  asm    mov    cx,addx        // any to finish up horizontally?
  281.  asm    jcxz    LOOP1a
  282.  asm    add    si,cx
  283.  asm    add    dx,cx
  284.  
  285.  LOOP1a:
  286.  asm    sub    di,width
  287.  asm    add    di,40
  288.  asm    dec    bh
  289.  asm    jnz    LOOP1
  290.  asm    mov    cx,addy        // any to finish up vertically?
  291.  asm    jcxz    LOOP1b
  292.  asm    add    si,cx
  293.  asm    add    dx,cx
  294.  
  295.  LOOP1b:
  296.  asm    inc    ah        // read from next plane
  297.  asm    shl    bl,1        // make sure we write to all planes!
  298.  asm    cmp    bl,16
  299.  asm    jb    LOOP0
  300.  
  301.  asm    popf
  302.  asm    pop    ds
  303.  asm    pop    di
  304.  asm    pop    si
  305. }
  306.  
  307.  
  308. ////////////////////////////////////////////////////////////
  309. //
  310. // DoEGAMblit : handles output of masked EGA grabs to the screen
  311. //
  312. ////////////////////////////////////////////////////////////
  313. void DoEGAMblit(int x,int y,int width,int height,int yadd,int hadd)
  314. {
  315.  int i,j;
  316.  
  317.  if (noshow || SkipToStart)
  318.    return;
  319.  
  320.  if (nostacking)
  321.    {
  322.     globalx=x;
  323.     globaly=y;
  324.     yadd=hadd=0;
  325.    }
  326.  else
  327.  if (yadd || hadd)
  328.    {
  329.     char huge *EGAscrn=MK_FP(0xa000,0);
  330.  
  331.     outport(GCindex,GCmode);
  332.  
  333.     for (j=globaly;j<globaly+yadd;j++)
  334.       for (i=globalx;i<globalx+width;i++)
  335.     {
  336.      outport(SCindex,SCmapmask | 0xf00);
  337.      *(EGAscrn+j*CurrentLBM.width/8+i)=0;
  338.      outport(SCindex,SCmapmask | ((ScreenColor^0xf)*256));
  339.      *(EGAscrn+j*CurrentLBM.width/8+i)=0xff;
  340.     }
  341.  
  342.     for (j=globaly+yadd+height;j<height+globaly+yadd+hadd;j++)
  343.       for (i=globalx;i<globalx+width;i++)
  344.     {
  345.      outport(SCindex,SCmapmask | 0xf00);
  346.      *(EGAscrn+j*CurrentLBM.width/8+i)=0;
  347.      outport(SCindex,SCmapmask | ((ScreenColor^0xf)*256));
  348.      *(EGAscrn+j*CurrentLBM.width/8+i)=0xff;
  349.     }
  350.    }
  351.  
  352.  EGAMblit(globalx,globaly+yadd,width,height,databuffer+offset);
  353.  if (!nostacking)
  354.    {
  355.     globalx+=width;
  356.     if (globalmaxh<height)
  357.       globalmaxh=height;
  358.     if (globalx>40-width)
  359.       {
  360.        globaly+=globalmaxh;
  361.        globalx=globalmaxh=0;
  362.       }
  363.    }
  364. }
  365.  
  366.  
  367. ////////////////////////////////////////////////////////////
  368. //
  369. // EGAMgrab: grabs any masked EGA shape from the screen buffer in main memory
  370. //           with INLINE asm for *FAST* grab!
  371. //         Of course, by John Romero!
  372. //
  373. // NOTE: I expect X & WIDTH to be in BYTE values, not pixels!
  374. //
  375. ////////////////////////////////////////////////////////////
  376. void EGAMgrab(int x,int y,int width,int height,long offset,int optimize)
  377. {
  378.  unsigned j,maskoff,ESreg,DIreg,SIreg,DSreg,size,scrnwid,tmpset=0;
  379.  
  380.  scrnwid=CurrentLBM.width/8;
  381.  size=scrnwid*CurrentLBM.height;    // EGA plane calculation
  382.  
  383.  //
  384.  // Does caller want vertical-seek optimization?
  385.  //
  386.  if (optimize)
  387.    {
  388.     Optimum.height=Optimum.y=0;
  389.  
  390.     for (i=y;i<y+height;i++)
  391.       {
  392.        for (j=x;j<x+width;j++)
  393.      if (*(maskscreen+i*scrnwid+j)!=0xff)
  394.        { Optimum.y=i; break; }
  395.        if (Optimum.y)
  396.      break;
  397.       }
  398.  
  399.     for (i=y+height-1;i>=0;i--)
  400.       {
  401.        for (j=x;j<x+width;j++)
  402.      if (*(maskscreen+i*scrnwid+j)!=0xff)
  403.        { Optimum.height=i-y; break; }
  404.        if (Optimum.height)
  405.      break;
  406.       }
  407.  
  408.     if (Optimum.height && Optimum.height!=height)
  409.       height=Optimum.height-(Optimum.y-y)+1;
  410.  
  411.     if (Optimum.y && Optimum.y!=y)
  412.       y=Optimum.y;
  413.    }
  414.  
  415.  
  416.  // FROM
  417.  SIreg=FP_OFF(maskscreen)+((scrnwid*y+x)&15);
  418.  DSreg=FP_SEG(maskscreen)+((scrnwid*y+x)/16);
  419.  
  420.  // TO
  421.  ESreg=FP_SEG(databuffer+offset);
  422.  DIreg=FP_OFF(databuffer+offset);
  423.  
  424.  asm        push    si
  425.  asm        push    di
  426.  asm        push    ds
  427.  
  428.  asm        mov    bx,height
  429.  asm        mov    dx,width
  430.  
  431.  asm        mov    es,ESreg
  432.  asm        mov    di,DIreg
  433.  asm        mov    si,SIreg
  434.  asm        mov    ax,DSreg
  435.  asm        mov    ds,ax
  436.  asm        cld
  437.  
  438.  LOOP0:
  439.  
  440.  asm        mov    cx,dx
  441.  
  442.  LOOP00:
  443.  asm        lodsb
  444.  asm        or    al,al
  445.  asm        jz    LOOP01
  446.  asm        mov    [tmpset],1
  447.  
  448.  LOOP01:
  449.  asm        stosb
  450.  asm        loop    LOOP00
  451.  
  452.  asm        sub    si,dx
  453.  asm        add    si,scrnwid
  454.  asm        dec    bx
  455.  asm        jnz    LOOP0
  456.  
  457.  asm        pop    ds
  458.  asm        pop    di
  459.  asm        pop    si
  460.  
  461.  maskoff=DIreg;
  462.  
  463.  for (i=0;i<4;i++)
  464.    {
  465.     // FROM
  466.     SIreg=FP_OFF(lbmscreen)+((size*i+(scrnwid*y+x))&15);
  467.     DSreg=FP_SEG(lbmscreen)+((size*i+(scrnwid*y+x))/16);
  468.  
  469.     // TO
  470.     DIreg+=width*height;
  471.  
  472.     asm        push    si
  473.     asm        push    di
  474.     asm        push    ds
  475.  
  476.     asm        mov    dx,width
  477.  
  478.     asm        mov    es,ESreg
  479.     asm        mov    di,DIreg    // DI=EGA data offset
  480.     asm        mov    si,SIreg    // SI=EGA screen offset
  481.     asm        mov    ds,DSreg
  482.     asm        mov    bx,maskoff    // BX=mask offset
  483.     asm        mov    ah,BYTE PTR height
  484.  
  485.     LOOP1:
  486.     asm        mov    cx,dx
  487.  
  488.     LOOP2:
  489.     asm        lodsb            // get EGA data
  490.     asm        mov    ch,[es:bx]    // get mask byte
  491.     asm        xor    ch,0xff        // and invert it!
  492.     asm        and    al,ch        // AND with mask
  493.     asm        xor    ch,ch        // make sure LOOP keeps going!
  494.     asm        stosb            // store
  495.     asm        inc    bx        // next mask byte
  496.     asm        loop LOOP2        // do all EGA bytes
  497.  
  498.     asm        sub    si,dx
  499.     asm        add    si,scrnwid
  500.     asm        dec    ah
  501.     asm        jnz    LOOP1
  502.  
  503.     asm        pop    ds
  504.     asm        pop    di
  505.     asm        pop    si
  506.    }
  507.  
  508.  //
  509.  // SEE IF WE NEED TO ELIMINATE THE MASK & SET THE
  510.  // BIT IN THE PACKED-BIT ARRAY. MASK-ELIMINATION IS
  511.  // DONE BY MOVING THE TILE DATA BACK OVER THE MASK.
  512.  //
  513.  setbit=tmpset^1;
  514.  
  515.  if (bit && setbit)
  516.    {
  517.     char masks[8]={0x80,0x40,0x20,0x10,8,4,2,1};
  518.     unsigned psize=width*height,domove=0;
  519.  
  520.     switch(type)
  521.     {
  522.      case TILE8MTYPE:
  523.      case ALT8MTYPE:
  524.        if (!cmpt8)
  525.      break;
  526.  
  527.        T8bit[T8whichbit/8]|=masks[T8whichbit%8];
  528.        domove=1;
  529.        break;
  530.      case TILE16MTYPE:
  531.      case ALT16MTYPE:
  532.        T16bit[T16whichbit/8]|=masks[T16whichbit%8];
  533.        domove=1;
  534.        break;
  535.      case TILE32MTYPE:
  536.      case ALT32MTYPE:
  537.        T32bit[T32whichbit/8]|=masks[T32whichbit%8];
  538.        domove=1;
  539.     }
  540.  
  541.     if (domove)
  542.       {
  543.        asm    push    si
  544.        asm    push    di
  545.        asm    push    ds
  546.  
  547.        asm    mov    di,[DIreg]
  548.        asm    mov    ax,[ESreg]
  549.        asm    mov    dx,[psize]
  550.        asm    mov    ds,ax
  551.        asm    mov    es,ax        // ES:DI - mask data
  552.        asm    mov    si,di
  553.        asm    add    si,dx        // DS:SI = tile data
  554.  
  555.        asm    mov    cx,dx        // move planesize*4 (all tile data)
  556.        asm    shl    cx,1
  557.        asm    shl    cx,1
  558.        asm    cld            // move forwards
  559.        asm    rep movsb
  560.  
  561.        asm    pop    ds
  562.        asm    pop    di
  563.        asm    pop    si
  564.       }
  565.    }
  566.  
  567. }
  568.